Kubernetes是一個知名的分散式管理、編排Container工具,幫助你將不同的dockerized的APP部屬在不同的環境中(e.g. 不同機器、不同雲端)的container。由Google開源並由GO語言撰寫。由於Kubernetes太長,很多人都稱他為K8S(中間有8個字母)。Kubernetes本身是一個希臘文,意思是船舵或是飛行員的,icon設計為一個船舵,得到了Kubernetes就能在雲端與Container化的暗潮中前行。
本文參考自:Kubernetes Crash Course for Absolute Beginners
Kubernetes解決了什麼? 現代化應用趨於MincroServices導致Container應用上升,過去常寫script來管理,但是這實在是太複雜了。因此Kubernetes作為編排Container工具誕生了。Kubernetes有以下幾個優點:
K8S可以區分成至少一個Master與許多Node(Worker)端。採Clustering架構,在Master中會有重要的4個執行部分:
Worker Node分成三個部分:
Virtual Network將Node之間、Master與Node之間串聯起來,簡單的來說,Virtual Machine將所有Clustering串聯起來成為一台大機器。
Kubernetes的重要component:
Node
: Virtula or Physic MachinePod
: Pod為K8s的最小執行單位,運行再Node上。可以看成是執行的container再外包一層用來與K8s溝通,每個Pod執行1個App (Node.js、DB)。把每個Pod看成是一個獨立的container,那彼此該怎麼溝通呢?整個K8S基於Virtual Machine來溝通,每一個Pod會得到他專屬的虛擬IP,彼此利用這個IP來互相溝通。
當一個Pod消失後(Container crash之類的原因),重新建立新的Pod不會繼承該IP(即使同樣的container)而會給予新的IP,這對App來說是個麻煩。解法如下:
Service
: 將虛擬IP與Pod的生命週期切開,Service會保留虛擬IP給下一個繼承該Service的PodIngress
: 一種內外橋接的Services,將外部網路轉換為虛擬網路的開口。假如今天要讓APP連接Server,我們會在程式內寫上Server的URL、PORT,當這些改變,就得重新build一個新的Image並pull出新的Pod。這就很麻煩了。
configMap
: 幫助你在pod外部輸入你的變數,並且可以在Pod運行中修改。我們只需要將程式內的變數改成configMap的參數即可。secrets
: 保存那些需要加密的變數,用法基本上同configMapvolumes
: 如Docker一樣,當pod消失data消失。要持久化保存應將資料存在Volumes,可以將資料存在local或是遠端其他K8s clustering中。將storge想成在clustering之外的插鍵,因為K8s並不管pod資料的保存。K8s採用clustering架構,為了能夠避免使用者服務暫停,我們可以將POD分配到多個Node之中,而每一個POD由Service所連結,因此可以獲得同樣的虛擬IP。Service同樣的可以用於load balance來動態調整Node之間的負擔。當一個Node上的pod死掉時可以經由另一個Node的Pod接手避免使用者服務中斷。
事實上,在開啟clustering時你不會建立第二個Pod,而是會定義一個pods的blueprint,確立會需要多少個pod複製。我們把這個blueprint稱作為Deployment。Deployment就是pod的blueprint,可以看成是pod的更上層封裝(正如pod是container的封裝來符合k8s的應用接口),Deployment讓你能夠更好的在分散式架構中擴展與刪減pods。
Deployment
: pods的blueprint,解釋如上。但是會發現如果我們要在資料庫上多開幾個Pod,他們就必須要share同一個data storage。多個database去存取一個data storage會發生data inconsistency的錯誤,也就是同一筆資料同時一個pod寫一個pod讀導致的錯誤。因此我們會在K8s建立Statefuleset來避免data inconsistency。
Statefulset
: 同Deployment來擴展與刪減pod,但是多了同步的功能來避免錯誤。不過其實Statefulset一般來說很難部屬,推薦將Database放在K8s clustering之外。